#include "dkglScene.h"

using namespace std;

namespace DKGL
{

	Root::Root()
	{
	}

	Root::~Root()
	{
	}

	void Root::addChild(MovablePtr movable)
	{
		_movableList.push_back(movable);
	}

	void Root::refresh()
	{
		std::list<MovablePtr>::iterator iter(_movableList.begin());
		std::list<MovablePtr>::iterator end(_movableList.end());

		for (;iter!=end;++iter)
		{
			(*iter)->updateTransform();
		}

	}

	Scene::Scene(const String& name) :
		_name(name),
		_enable(true)
	{
		//m_backgroundColor = Colorf::BLACK;
		//skybox = new SkyBox();
	}
	
	Scene::~Scene()
	{
		//map<std::string, Camera*>::iterator it;
		//for(it=mCameraList.begin();it!=mCameraList.end();it++)
		//	delete (*it).second;
	}

	//SkyBox* Scene::getSkyBox()
	//{
	//	//if (!skyboxPtr.get())

	//	return NULL;

	//}

	void Scene::refresh()
	{
		if(!_enable)
			return;

		float m[16], x, y, z;


		//glClearColor(m_backgroundColor.r, m_backgroundColor.g, m_backgroundColor.b, m_backgroundColor.a);

		map<String, CameraPtr>::iterator iter(_cameraMap.begin());
		map<String, CameraPtr>::iterator end(_cameraMap.end());

		for(;iter!=end;++iter)
		{
			iter->second->look();

			//glGetFloatv(GL_MODELVIEW_MATRIX, m);
			//x = m[12]; y = m[13]; z = m[14];
			//m[12] = 0; m[13] = 0; m[14] = 0;

			//glPushMatrix();
			//glLoadMatrixf(m);
			//// render the skybox first
			//skybox->drawEntity();
			//glPopMatrix();

			_root.refresh();
		}
	}

	
	CameraPtr Scene::createCamera(const String& name)
	{
		map<String, CameraPtr>::iterator iter(_cameraMap.find(name));

		if(iter!=_cameraMap.end())
		{
			throw std::logic_error("");
		}

		CameraPtr cptr = CameraPtr(new Camera(name));
		_cameraMap[name] = cptr;
		return cptr;
	}


	void Scene::destroyCamera(const String& name)
	{
		map<String, CameraPtr>::iterator iter(_cameraMap.find(name));

		if (iter!=_cameraMap.end())
		{
			_cameraMap.erase(iter);
		}
	}




	SceneManager::SceneManager()
	{
	}


	SceneManager::~SceneManager()
	{
	}

	void SceneManager::refresh()
	{
		map<String, ScenePtr>::iterator iter(_sceneMap.begin());
		map<String, ScenePtr>::iterator end(_sceneMap.end());

		for(;iter!=end;++iter)
		{
			iter->second->refresh();
		}
	}


	ScenePtr SceneManager::createScene(const String& name)
	{
		if(_sceneMap.find(name)!=_sceneMap.end())
		{
			throw std::logic_error("name collision");
			//Log::dump("Name Collision when create a new Scene");
		}

		ScenePtr sp = ScenePtr(new Scene(name));
		_sceneMap[name] = sp;
		//Log::dump("Create a new scene: " + name);
		return sp;
	}


	void SceneManager::destroyScene(const String& name)
	{
		map<String, ScenePtr>::iterator iter(_sceneMap.find(name));
		if (iter!=_sceneMap.end())
		{
			_sceneMap.erase(iter);
		}
	}

	ScenePtr SceneManager::getScenePtr(const String& name)
	{
		map<String, ScenePtr>::iterator iter(_sceneMap.find(name));
		if(iter==_sceneMap.end())
		{
			throw std::runtime_error("");
		}

		return iter->second;
	}
}